Increase download speed from MTK Logger by requesting multiple chunks at once
authorMykhaylo Yehorov <yehorov@gmail.com>
Thu, 4 Aug 2016 20:27:02 +0000 (23:27 +0300)
committerMykhaylo Yehorov <yehorov@gmail.com>
Thu, 4 Aug 2016 20:27:02 +0000 (23:27 +0300)
mtk_logger.cc

index 51f3b1283ee3a34b1c72f308d27a3b5606deaef8..601043421c0e9e550953cbd1efac1a894ba82878 100644 (file)
@@ -227,6 +227,7 @@ static char* OPT_erase;  /* erase ? command option */
 static char* OPT_erase_only;  /* erase_only ? command option */
 static char* OPT_log_enable;  /* enable ? command option */
 static char* csv_file; /* csv ? command option */
+static char* OPT_block_size; /* block_size ? command option */
 static enum MTK_DEVICE_TYPE mtk_device = MTK_LOGGER;
 
 struct mtk_loginfo mtk_info;
@@ -267,6 +268,10 @@ static arglist_t mtk_sargs[] = {
     "csv",   &csv_file, "MTK compatible CSV output file",
     NULL, ARGTYPE_STRING, ARG_NOMINMAX
   },
+  {
+    "block_size", &OPT_block_size, "Size of blocks to request from device",
+    "1024", ARGTYPE_INT, "1024", "65536"
+  },
   ARG_TERMINATOR
 };
 
@@ -531,8 +536,9 @@ static void mtk_read(void)
   char cmd[256];
   char* line = NULL;
   unsigned char crc, *data = NULL;
-  int cmdLen, j, bsize, i, len, ff_len, null_len, rc, init_scan, retry_cnt, log_enabled;
-  unsigned int line_size, data_size, data_addr, addr, addr_max;
+  int cmdLen, i, len, rc, init_scan, retry_cnt, log_enabled;
+  unsigned int j, bsize, scan_bsize, read_bsize, scan_step, ff_len, null_len, chunk_size;
+  unsigned int line_size, data_size, data_addr, addr, addr_max, rcvd_addr, rcvd_bsize;
   unsigned long dsize, dpos = 0;
   FILE* dout;
   char* fusage = NULL;
@@ -608,11 +614,22 @@ static void mtk_read(void)
     }
   }
 
-  bsize = 0x0400;
+  scan_step = 0x10000;
+  scan_bsize = 0x0400;
+  read_bsize = strtol(OPT_block_size, NULL, 0);
+  if (errno == ERANGE || read_bsize < 0x0400) {
+    read_bsize = 0x0400;
+  }
+  dbg(2, "Download block size is %d bytes\n", read_bsize);
+  if (init_scan) {
+    bsize = scan_bsize;
+  } else {
+    bsize = read_bsize;
+  }
   addr  = 0x0000;
 
-  line_size = 2*bsize + 32; // logdata as nmea/hex.
-  data_size = bsize + 32;
+  line_size = 2*read_bsize + 32; // logdata as nmea/hex.
+  data_size = read_bsize + 32;
   if ((line = (char*) xmalloc(line_size)) == NULL) {
     fatal(MYNAME ": Can't allocate %u bytes for NMEA buffer\n",  line_size);
   }
@@ -636,6 +653,7 @@ mtk_retry:
     do_send_cmd(cmd, cmdLen);
 
     memset(line, '\0', line_size);
+    rcvd_addr = addr;
     do {
       rc = gbser_read_line(fd, line, line_size-1, TIMEOUT, 0x0A, 0x0D);
       if (rc != gbser_OK) {
@@ -654,12 +672,12 @@ mtk_retry:
         if (strncmp(line, "$PMTK182,8", 10) == 0) { //  $PMTK182,8,00005000,FFFFFFF
           retry_cnt = 0;
           data_addr = strtoul(&line[11], NULL, 16);
-          fseek(dout, data_addr, SEEK_SET);
+          // fixme - we should check if all data before data_addr is already received
           i = 20;
-          j = 0;
+          j = data_addr - addr;
           ff_len = 0; // number of 0xff bytes.
           null_len = 0; // number of 0x00 bytes.
-          while (i < (len-3)) {
+          while (i + 3 < len && j < data_size) {
             data[j] = (isdigit(line[i])?(line[i]-'0'):(line[i]-'A'+0xA))*0x10 +
                       (isdigit(line[i+1])?(line[i+1]-'0'):(line[i+1]-'A'+0xA));
             if (data[j] == 0xff) {
@@ -671,34 +689,24 @@ mtk_retry:
             i += 2;
             j++;
           }
+          rcvd_addr = addr + j;
+          chunk_size = rcvd_addr - data_addr;
           if (init_scan) {
-            if (dsize > 0 && addr < dsize) {
-              fseek(dout, addr, SEEK_SET);
-              if (fread(line, 1, bsize, dout) == bsize && memcmp(line, data, bsize) == 0) {
-                dpos = addr;
-                dbg(2, "%s same at %d\n", TEMP_DATA_BIN, addr);
-              } else {
-                dbg(2, "%s differs at %d\n", TEMP_DATA_BIN, addr);
-              }
-            }
-            if (ff_len == j) {  // data in sector - we've found max sector..
-              addr_max = addr;
+            if (ff_len == chunk_size) {  // data in sector - we've found max sector..
+              addr_max = data_addr;
+              rcvd_addr = data_addr;
               dbg(1, "Initial scan done - Download %dkB from device\n", (addr_max+1) >> 10);
+              break;
             }
-            len = 0;
           } else {
-            if (null_len == j) {  // 0x00 block - bad block....
+            if (null_len == chunk_size) {  // 0x00 block - bad block....
               fprintf(stderr, "FIXME -- read bad block at 0x%.6x - retry ? skip ?\n%s\n", data_addr, line);
             }
-            if (fwrite(data, 1, j, dout) != j) {
-              fatal(MYNAME ": Failed to write temp. binary file\n");
-            }
-            if (ff_len == j) {  // 0xff block - read complete...
+            if (ff_len == chunk_size) {  // 0xff block - read complete...
               len = ff_len;
-              addr_max = addr;
+              addr_max = data_addr;
+              rcvd_addr = data_addr;
               break;
-            } else {
-              len = 0;
             }
           }
         } else if (strncmp(line, "$PMTK001,182,7,", 15) == 0) {  // Command ACK
@@ -711,15 +719,38 @@ mtk_retry:
           }
         }
       }
-    } while (len != 0);
+    } while (rcvd_addr < addr + bsize);
+
+    rcvd_bsize = rcvd_addr - addr;
+    dbg(2, "Received %d bytes\n", rcvd_bsize);
+
     if (init_scan) {
-      addr += 0x10000;
-      if (addr >= addr_max) {  // initial scan complete...
-        init_scan = 0;
-        addr = dpos;
+      if (dsize > 0 && addr < dsize) {
+        fseek(dout, addr, SEEK_SET);
+        if (fread(line, 1, rcvd_bsize, dout) == rcvd_bsize && memcmp(line, data, rcvd_bsize) == 0) {
+          dpos = addr;
+          dbg(2, "%s same at %d\n", TEMP_DATA_BIN, addr);
+        } else {
+          dbg(2, "%s differs at %d\n", TEMP_DATA_BIN, addr);
+          init_scan = 0;
+          addr = dpos;
+          bsize = read_bsize;
+        }
+      }
+      if (init_scan) {
+        addr += scan_step;
+        if (addr >= addr_max) {  // initial scan complete...
+          init_scan = 0;
+          addr = dpos;
+          bsize = read_bsize;
+        }
       }
     } else {
-      addr += bsize;
+      fseek(dout, addr, SEEK_SET);
+      if (fwrite(data, 1, rcvd_bsize, dout) != rcvd_bsize) {
+        fatal(MYNAME ": Failed to write temp. binary file\n");
+      }
+      addr += rcvd_bsize;
       if (global_opts.verbose_status || (global_opts.debug_level >= 2 && global_opts.debug_level < 5)) {
         int perc;
         perc = 100 - 100*(addr_max-addr)/addr_max;
@@ -731,6 +762,7 @@ mtk_retry:
     }
   }
   if (dout != NULL) {
+    ftruncate(fileno(dout), addr_max);
     fclose(dout);
   }
   if (global_opts.verbose_status || (global_opts.debug_level >= 2 && global_opts.debug_level < 5)) {